' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
' ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
' THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
' PARTICULAR PURPOSE.
'
' Copyright (c) 2006 Microsoft Corporation. All rights reserved.

' Original code from the Microsoft Windows SDK for Windows Vista.

Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Net
Imports System.Xml
Imports Microsoft.Feeds.Interop

''' <summary>
''' Representation of an RSS element in a RSS 2.0 XML document.
''' </summary>
Public Class RssFeed
    Implements IItem

    Private ReadOnly _title As String
    Private ReadOnly _link As String
    Private ReadOnly _description As String
    Private ReadOnly _path As String
    Private ReadOnly _lastWriteTime As DateTime
    Private _items As List(Of RssItem)

    Public ReadOnly Property Title() As String Implements IItem.Title
        Get
            Return Me._title
        End Get
    End Property
    Public ReadOnly Property Link() As String
        Get
            Return Me._link
        End Get
    End Property
    Public ReadOnly Property Description() As String Implements IItem.Description
        Get
            Return Me._description
        End Get
    End Property
    Public ReadOnly Property Path() As String
        Get
            Return Me._path
        End Get
    End Property
    Public ReadOnly Property LastWriteTime() As DateTime
        Get
            Return Me._lastWriteTime
        End Get
    End Property
    Public ReadOnly Property Items() As IList(Of RssItem)
        Get
            Return Me._items.AsReadOnly()
        End Get
    End Property

    ''' <summary>
    ''' Private constructor to be used with factory pattern.  
    ''' </summary>
    ''' <exception cref="System.Xml.XmlException">Occurs when the XML is not well-formed.</exception>
    ''' <param name="xmlNode">An XML block containing the RSSFeed content.</param>
    Private Sub New(ByVal xmlNode As XmlNode)
        Dim channelNode As XmlNode = xmlNode.SelectSingleNode("rss/channel")
        Me._items = New List(Of RssItem)()
        Me._title = channelNode.SelectSingleNode("title").InnerText
        Me._link = channelNode.SelectSingleNode("link").InnerText
        Me._description = channelNode.SelectSingleNode("description").InnerText

        Dim itemNodes As XmlNodeList = channelNode.SelectNodes("item")
        For Each itemNode As XmlNode In itemNodes
            Dim rssItem As RssItem = New RssItem(itemNode)

            ' only add items that have enclosures.
            If Not rssItem.Enclosure Is Nothing Then
                Me._items.Add(rssItem)
            End If
        Next itemNode
    End Sub

    Private Sub New(ByVal feed As IFeed)
        Me._items = New List(Of RssItem)()
        Me._title = feed.Title
        Me._link = feed.Link
        Me._description = feed.Description
        Me._path = feed.Path
        Me._lastWriteTime = feed.LastWriteTime

        For Each item As IFeedItem In CType(feed.Items, IFeedsEnum)
            Dim rssItem As RssItem = New RssItem(item)

            ' only add items that have enclosures.
            If Not rssItem.Enclosure Is Nothing Then
                Me._items.Add(rssItem)
            End If
        Next item
    End Sub

    Public Shared Function FromUri(ByVal uri As Uri) As RssFeed
        Dim xmlDoc As XmlDocument
        Dim webClient As WebClient = New WebClient()
        Using rssStream As Stream = webClient.OpenRead(uri)
            Dim textReader As TextReader = New StreamReader(rssStream)
            Dim reader As XmlTextReader = New XmlTextReader(textReader)
            xmlDoc = New XmlDocument()
            xmlDoc.Load(reader)
        End Using
        Return New RssFeed(xmlDoc)
    End Function

    ''' <summary>
    ''' Factory to construct the RSSFeed object from the Windows RSS Platform API.
    ''' </summary>
    ''' <param name="feed">The Common Feed List feed object.</param>
    ''' <returns>An initialized RSSFeed object.</returns>
    Friend Shared Function FromApi(ByVal feed As IFeed) As RssFeed
        Dim rssFeed As RssFeed = Nothing

        ' Skip this feed if there are no items.
        If Not feed Is Nothing AndAlso (CType(feed.Items, IFeedsEnum)).Count > 0 Then
            rssFeed = New RssFeed(feed)
        End If
        Return rssFeed
    End Function

    ''' <summary>
    ''' Factory that constructs RssFeed objects from the text of an RSS 2.0 XML file.
    ''' </summary>
    ''' <param name="rssText">A string containing the XML for the RSS feed.</param>
    Public Shared Function FromText(ByVal rssText As String) As RssFeed
        Dim xmlDoc As XmlDocument = New XmlDocument()
        xmlDoc.LoadXml(rssText)
        Return New RssFeed(xmlDoc)
    End Function

End Class